package dal;

import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NamedParameterPreparedStatement {

	private Hashtable<String, Integer> paramIndexes = new Hashtable<String, Integer>();
	private PreparedStatement st = null;

	// \w A word character: [a-zA-Z_0-9]
	private final static String regEx = ":(\\w)*";

	public NamedParameterPreparedStatement(Connection dbConn, String sql)
			throws SQLException {
		// create parameter index table
		paramIndexes = genHastable(sql);

		// 2011-11-17 Huy Le for debug
		System.out.println(sql);

		// replace params by "?"
		String standardSql = sql.replaceAll(regEx, "?");
		st = dbConn.prepareStatement(standardSql);
	}

	private static Hashtable<String, Integer> genHastable(String sql) {
		// http://java.sun.com/developer/technicalArticles/releases/1.4regex/

		Pattern p = Pattern.compile(regEx);
		Matcher matcher = p.matcher(sql);

		Hashtable<String, Integer> ht = new Hashtable<String, Integer>();

		int index = 1;
		while (matcher.find()) {
			String key = sql.substring(matcher.start(), matcher.end());
			ht.put(key.replace(":", ""), index);
			index++;
		}

		return ht;
	}

	public PreparedStatement getPreparedStatement() {
		return st;
	}

	public void setObject(String paramName, Object x) throws SQLException {
		int index = paramIndexes.get(paramName);
		if (x instanceof java.util.Date) {
			java.util.Date utilDate = (java.util.Date) x;
			java.sql.Timestamp sqlDate = new java.sql.Timestamp(
					utilDate.getTime());
			st.setObject(index, sqlDate);
		} else if (x instanceof Double) {
			Double y = (Double) x;
			java.math.BigDecimal d = new java.math.BigDecimal(y);
			st.setObject(index, d);
		} else {
			st.setObject(index, x);
		}
	}

	// public void setBoolean(String paramName, boolean x) throws SQLException {
	// int index = paramIndexes.get(paramName);
	// st.setBoolean(index, x);
	// }
	//
	// public void setDate(String paramName, Date x) throws SQLException {
	// int index = paramIndexes.get(paramName);
	// st.setDate(index, x);
	// }
	//
	// public void setDouble(String paramName, Double x) throws SQLException {
	// int index = paramIndexes.get(paramName);
	// st.setDouble(index, x);
	// }
	//
	// public void setFloat(String paramName, Float x) throws SQLException {
	// int index = paramIndexes.get(paramName);
	// st.setFloat(index, x);
	// }
	//
	// public void setInt(String paramName, int x) throws SQLException {
	// int index = paramIndexes.get(paramName);
	// st.setInt(index, x);
	// }

}